package jp.ac.waseda.cs.washi.game.entity;

import java.awt.Image;
import java.util.ArrayList;

import jp.ac.waseda.cs.washi.game.api.CharaInfo;
import jp.ac.waseda.cs.washi.gameaiarena.api.Direction4;
import jp.ac.waseda.cs.washi.gameaiarena.api.Point2;
import jp.ac.waseda.cs.washi.game.api.PumpkinInfo;
import jp.ac.waseda.cs.washi.game.api.PumpkinType;
import jp.ac.waseda.cs.washi.gameaiarena.gui.Renderer;

public class Chara {
	class CharaInfoImpl implements CharaInfo {

		@Override
		public Point2 getLocation() {
			return Chara.this.getLocation();
		}

		@Override
		public int getScore() {
			return Chara.this.getScore();
		}

		@Override
		public ArrayList<PumpkinInfo> getPumpkins() {
			ArrayList<PumpkinInfo> result = new ArrayList<PumpkinInfo>();
			for (Pumpkin pump : Chara.this.getPumpkins()) {
				result.add(pump.getInfo());
			}
			return result;
		}

		@Override
		public ArrayList<PumpkinInfo> getMiniPumpkins() {
			ArrayList<PumpkinInfo> result = new ArrayList<PumpkinInfo>();
			for (Pumpkin pump : Chara.this.getPumpkins()) {
				if (pump.getType() == PumpkinType.MiniPumpkin)
					result.add(pump.getInfo());
			}
			return result;
		}

		@Override
		public ArrayList<PumpkinInfo> getKingPumpkins() {
			ArrayList<PumpkinInfo> result = new ArrayList<PumpkinInfo>();
			for (Pumpkin pump : Chara.this.getPumpkins()) {
				if (pump.getType() == PumpkinType.KingPumpkin)
					result.add(pump.getInfo());
			}
			return result;
		}

		@Override
		public ArrayList<Point2> getPumpkinCenterLocations() {
			ArrayList<Point2> result = new ArrayList<Point2>();
			for (Pumpkin pump : Chara.this.getPumpkins()) {
				result.add(pump.getCenterLocation());
			}
			return result;
		}

		@Override
		public ArrayList<Point2> getMiniPumpkinCenterLocations() {
			ArrayList<Point2> result = new ArrayList<Point2>();
			for (Pumpkin pump : Chara.this.getPumpkins()) {
				if (pump.getType() == PumpkinType.MiniPumpkin)
					result.add(pump.getCenterLocation());
			}
			return result;
		}

		@Override
		public ArrayList<Point2> getKingPumpkinCenterLocations() {
			ArrayList<Point2> result = new ArrayList<Point2>();
			for (Pumpkin pump : Chara.this.getPumpkins()) {
				if (pump.getType() == PumpkinType.KingPumpkin)
					result.add(pump.getCenterLocation());
			}
			return result;
		}
	}

	/**
	 * 現在地
	 */
	private Point2 _location;

	/**
	 * 向いている方向
	 */
	private Direction4 _direction;

	private ArrayList<Pumpkin> _pumpkins = new ArrayList<Pumpkin>();
	private int _breakScore;
	private int _score;
	private int _imageIndex;
	private MassSpellType _massSpellType;

	public Image[][] _charaImages;
	public Image[] _owneredWallEquipImages;
	public Image[] _territoryImages;
	public Image[] _pumpkinImages;

	private final CharaInfo _info;

	public Chara(Point2 startLocation, Image[][] charaImages,
			Image magicalCircleImage, Image[] territoryImages,
			Image[] pumpkinImages) {
		_direction = Direction4.DOWN;

		_location = startLocation;
		_info = new CharaInfoImpl();

		_massSpellType = MassSpellType.SingleType;

		_charaImages = charaImages;
		_territoryImages = territoryImages;
		_pumpkinImages = pumpkinImages;
	}

	public CharaInfo getInfo() {
		return _info;
	}

	// キャラの位置を取得する
	public Point2 getLocation() {
		return _location;
	}

	// キャラが選択している範囲魔法タイプを取得する
	public MassSpellType getMassSpellType() {
		return _massSpellType;
	}

	// キャラが選択している範囲魔法タイプを変更する
	public void changeMassSpellType(MassSpellType massSpellType) {
		_massSpellType = massSpellType;
	}

	// キャラの向きを取得する
	public Direction4 getDirection() {
		return _direction;
	}

	// キャラの向きを変更する
	public void changeDirection(Direction4 direction) {
		_direction = direction;
	}

	// 移動する
	public void move(Direction4 direction) {
		_location = _location.move(direction);
		_imageIndex++;
	}

	public void warp(Point2 location) {
		_location = location;
	}

	// キャラの描画
	public void draw(Renderer render, GameTime gameTime) {
		Image[] images = _charaImages[_direction.ordinal()];
		render.drawImage(images[_imageIndex % images.length], _location.x
				* Map.BLOCK_WIDTH, _location.y * Map.BLOCK_HEIGHT - 16);
	}

	public Image[] getTerritoryImages() {
		return _territoryImages;
	}

	public Image[] getPumpkinImages() {
		return _pumpkinImages;
	}

	public void setScore(int point) {
		_score = point;
	}

	public int getScore() {
		return _score;
	}

	public void addBreakScore() {
		_breakScore++;
	}

	public int getBreakScore() {
		return _breakScore;
	}

	public ArrayList<Pumpkin> getPumpkins() {
		return _pumpkins;
	}
}
